<template>
  <div class="scroll-list" ref="scrollContainer" @scroll="onScroll">
    <div
      v-for="(item, index) in list"
      :key="index"
      class="list-item">
      {{ item }}
    </div>
    <div class="loading" v-show="loading">
      加载中...
    </div>
  </div>
</template>

<script>

export default {
  data() {
    return {
      list: ["test 1", "test 2"],
      offset: 30,
      lastScrollTop: 0,
      loading: false
    }
  },
  
  mounted() {
    this.checkScrollContainer();
  },
  methods: {
    onScroll() {
      let target = this.$refs['scrollContainer'];
      let { scrollTop, scrollHeight } = target
      if (scrollHeight - scrollTop > this.offset && scrollTop > this.lastScrollTop) {
        // emit
        this.getData();
      }
      this.lastScrollTop = scrollTop;
    },

    checkScrollContainer() {
      let container = this.$refs['scrollContainer'];
      let {height} = container.getBoundingClientRect();
      console.dir({
        height, 
        scrollHeight: container.scrollHeight
      })
      if (container.scrollHeight <= height) {
        this.getData();
      }
    },

    getData() {
      if (!this.loading) {
      this.loading = true;
        this.fetch()
          .then(data => {
            this.list.push(...data);
            this.$nextTick(() => {
              this.checkScrollContainer();
            })
          })
          .finally(() => {
            this.loading = false;
          }) 
      }
    },

    fetch() {
      return new Promise(resolve => {
        setTimeout(() => {
          let currentLength = this.list.length;
          resolve(new Array(10).fill(0).map((item, index) => `test ${currentLength + index}`))
        }, 1000);
      })
    }
  }
}
</script>


<style scoped>
.scroll-list {
  height: 500px;
  overflow: auto;
  border: 1px solid #ccc;
  box-sizing: border-box;
}
.loading {
  text-align: center;
  padding: 20px;
}
.list-item {
  padding: 10px;
  border: 1px solid #aaa;
  margin: 10px;
}
</style>